using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using JGSY.CMS.LowCode.Platform.Application.DTOs;
using JGSY.CMS.LowCode.Platform.Application.DTOs.Common;
using JGSY.CMS.LowCode.Platform.Application.Interfaces;
using JGSY.CMS.LowCode.Platform.Domain.Enums;

namespace JGSY.CMS.LowCode.Platform.Controllers
{
    /// <summary>
    /// 分类管理接口
    /// </summary>
    /// <remarks>
    /// 提供分类的完整生命周期管理功能，包括：
    /// <list type="bullet">
    /// <item>分类的创建、查询、更新、删除操作</item>
    /// <item>分类树形结构管理</item>
    /// <item>分类层级关系维护</item>
    /// <item>分类状态管理(启用/禁用)</item>
    /// <item>分类排序和路径管理</item>
    /// </list>
    /// 
    /// <para><strong>权限要求:</strong></para>
    /// <list type="bullet">
    /// <item>查询操作: 需要 CATEGORY_VIEW 权限</item>
    /// <item>创建操作: 需要 CATEGORY_CREATE 权限</item>
    /// <item>更新操作: 需要 CATEGORY_UPDATE 权限</item>
    /// <item>删除操作: 需要 CATEGORY_DELETE 权限</item>
    /// </list>
    /// </remarks>
    [ApiController]
    [Route("api/[controller]")]
    [Produces("application/json")]
    [Authorize]
    public class CategoriesController : ControllerBase
    {
        private readonly ICategoryAppService _categoryService;
        private readonly ILogger<CategoriesController> _logger;

        public CategoriesController(
            ICategoryAppService categoryService,
            ILogger<CategoriesController> logger)
        {
            _categoryService = categoryService;
            _logger = logger;
        }

        /// <summary>
        /// 分页查询分类列表
        /// </summary>
        /// <remarks>
        /// 支持多条件分页查询分类列表，包括：
        /// <list type="bullet">
        /// <item>关键字搜索(名称、编码、描述)</item>
        /// <item>按状态筛选</item>
        /// <item>多字段排序</item>
        /// </list>
        /// 
        /// <para><strong>查询参数说明:</strong></para>
        /// <list type="bullet">
        /// <item><c>pageIndex</c>: 页码，从1开始，默认值为1</item>
        /// <item><c>pageSize</c>: 每页大小，范围1-100，默认值为20</item>
        /// <item><c>keyword</c>: 搜索关键字，支持名称、编码模糊匹配</item>
        /// <item><c>status</c>: 状态筛选，null表示不筛选</item>
        /// <item><c>sortBy</c>: 排序字段，可选值：name, code, createdAt, sortOrder</item>
        /// <item><c>sortDesc</c>: 是否降序排序，false表示升序，true表示降序</item>
        /// </list>
        /// </remarks>
        /// <param name="pageIndex">页码，从1开始</param>
        /// <param name="pageSize">每页大小，1-100之间</param>
        /// <param name="keyword">搜索关键字，支持名称、编码模糊匹配</param>
        /// <param name="type">分类类型筛选(暂未使用，为扩展预留)</param>
        /// <param name="status">状态筛选</param>
        /// <param name="sortBy">排序字段，可选值：name, code, createdAt, sortOrder</param>
        /// <param name="sortDesc">是否降序排序</param>
        /// <returns>分页的分类列表</returns>
        /// <response code="200">查询成功，返回分类列表数据</response>
        /// <response code="400">参数错误，如页码小于1、每页大小超出范围等</response>
        /// <response code="401">未授权，需要登录</response>
        /// <response code="403">权限不足，需要CATEGORY_VIEW权限</response>
        /// <response code="500">服务器内部错误</response>
        [HttpGet]
        [ProducesResponseType(typeof(PagedResultDto<CategoryDto>), 200)]
        [ProducesResponseType(typeof(object), 400)]
        [ProducesResponseType(401)]
        [ProducesResponseType(403)]
        [ProducesResponseType(500)]
        public async Task<ActionResult<PagedResultDto<CategoryDto>>> GetPagedList(
            [FromQuery, Range(1, int.MaxValue, ErrorMessage = "页码必须大于0")] int pageIndex = 1,
            [FromQuery, Range(1, 100, ErrorMessage = "每页大小必须在1-100之间")] int pageSize = 20,
            [FromQuery, StringLength(100, ErrorMessage = "搜索关键字长度不能超过100个字符")] string? keyword = null,
            [FromQuery, StringLength(50, ErrorMessage = "分类类型长度不能超过50个字符")] string? type = null,
            [FromQuery] byte? status = null,
            [FromQuery, RegularExpression("^(name|code|createdAt|sortOrder)$", ErrorMessage = "无效的排序字段")] string? sortBy = "sortOrder",
            [FromQuery] bool sortDesc = false)
        {
            try
            {
                var query = new PagedQueryDto
                {
                    PageIndex = pageIndex,
                    PageSize = pageSize,
                    Keyword = keyword,
                    SortBy = sortBy,
                    SortDesc = sortDesc,
                    Status = status
                };

                // 标准化查询参数
                query.Normalize();

                var result = await _categoryService.GetPagedListAsync(query);
                return Ok(result);
            }
            catch (ArgumentException ex)
            {
                _logger.LogWarning(ex, "Invalid parameters for getting paged categories: {Message}", ex.Message);
                return BadRequest(new { 
                    success = false,
                    message = ex.Message,
                    errorCode = "1001", // INVALID_PARAMETERS
                    timestamp = DateTime.UtcNow,
                    traceId = HttpContext.TraceIdentifier
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting paged categories");
                return StatusCode(500, new { 
                    success = false,
                    message = "服务器内部错误",
                    errorCode = "5000", // INTERNAL_SERVER_ERROR
                    timestamp = DateTime.UtcNow,
                    traceId = HttpContext.TraceIdentifier
                });
            }
        }

        /// <summary>
        /// 获取树形分类列表
        /// </summary>
        /// <param name="type">分类类型</param>
        /// <param name="parentId">父分类ID</param>
        /// <returns>树形分类列表</returns>
        [HttpGet("tree")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<List<CategoryDto>>> GetTree([FromQuery] string? type, [FromQuery] long? parentId)
        {
            try
            {
                var result = await _categoryService.GetTreeAsync(type, parentId);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting category tree");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 根据类型获取分类列表
        /// </summary>
        /// <param name="type">分类类型</param>
        /// <returns>分类列表</returns>
        [HttpGet("type/{type}")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<List<CategoryDto>>> GetByType(string type)
        {
            try
            {
                var result = await _categoryService.GetByTypeAsync(type);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting categories by type {Type}", type);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 根据ID获取分类详情
        /// </summary>
        /// <param name="id">分类ID</param>
        /// <returns>分类详情</returns>
        [HttpGet("{id:long}")]
        [ProducesResponseType(200)]
        [ProducesResponseType(404)]
        [AllowAnonymous]
        public async Task<ActionResult<CategoryDto>> GetById(long id)
        {
            try
            {
                var result = await _categoryService.GetByIdAsync(id);
                if (result == null)
                {
                    return NotFound();
                }
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting category {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 根据路径获取分类
        /// </summary>
        /// <param name="path">分类路径</param>
        /// <returns>分类信息</returns>
        [HttpGet("path")]
        [ProducesResponseType(200)]
        [ProducesResponseType(404)]
        [AllowAnonymous]
        public async Task<ActionResult<CategoryDto>> GetByPath([FromQuery] string path)
        {
            try
            {
                var result = await _categoryService.GetByPathAsync(path);
                if (result == null)
                {
                    return NotFound();
                }
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting category by path {Path}", path);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 创建分类
        /// </summary>
        /// <param name="dto">分类数据</param>
        /// <returns>创建的分类</returns>
        [HttpPost]
        [ProducesResponseType(201)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<CategoryDto>> Create([FromBody] CategoryDto dto)
        {
            try
            {
                var result = await _categoryService.CreateAsync(dto);
                return CreatedAtAction(nameof(GetById), new { id = result.Id }, result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error creating category");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 更新分类
        /// </summary>
        /// <param name="id">分类ID</param>
        /// <param name="dto">更新的分类数据</param>
        /// <returns>更新后的分类</returns>
        [HttpPut("{id:long}")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        [ProducesResponseType(404)]
        public async Task<ActionResult<CategoryDto>> Update(long id, [FromBody] CategoryDto dto)
        {
            try
            {
                var result = await _categoryService.UpdateAsync(id, dto);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error updating category {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 删除分类
        /// </summary>
        /// <param name="id">分类ID</param>
        /// <param name="deleteChildren">是否删除子分类</param>
        /// <returns>删除结果</returns>
        [HttpDelete("{id:long}")]
        [ProducesResponseType(200)]
        [ProducesResponseType(404)]
        public async Task<ActionResult<bool>> Delete(long id, [FromQuery] bool deleteChildren = false)
        {
            try
            {
                var result = await _categoryService.DeleteAsync(id, deleteChildren);
                if (!result)
                {
                    return NotFound();
                }
                return Ok(new { success = true });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error deleting category {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 批量删除分类
        /// </summary>
        /// <param name="request">批量删除请求</param>
        /// <returns>删除结果</returns>
        [HttpPost("batch-delete")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<bool>> BatchDelete([FromBody] JGSY.CMS.LowCode.Platform.Application.DTOs.BatchDeleteRequest request)
        {
            try
            {
                var result = await _categoryService.BatchDeleteAsync(request.Ids, request.DeleteChildren);
                return Ok(new { success = result });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error batch deleting categories");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 移动分类
        /// </summary>
        /// <param name="id">分类ID</param>
        /// <param name="request">移动请求</param>
        /// <returns>移动结果</returns>
        [HttpPost("{id:long}/move")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<bool>> Move(long id, [FromBody] MoveCategoryRequest request)
        {
            try
            {
                var result = await _categoryService.MoveAsync(id, request.NewParentId);
                return Ok(new { success = result });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error moving category {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 获取分类的子分类
        /// </summary>
        /// <param name="parentId">父分类ID</param>
        /// <param name="includeDisabled">是否包含禁用的分类</param>
        /// <returns>子分类列表</returns>
        [HttpGet("{parentId:long}/children")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<List<CategoryDto>>> GetChildren(long parentId, [FromQuery] bool includeDisabled = false)
        {
            try
            {
                var result = await _categoryService.GetChildrenAsync(parentId, includeDisabled);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting children for category {ParentId}", parentId);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 获取分类的所有祖先分类
        /// </summary>
        /// <param name="id">分类ID</param>
        /// <returns>祖先分类列表</returns>
        [HttpGet("{id:long}/ancestors")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<List<CategoryDto>>> GetAncestors(long id)
        {
            try
            {
                var result = await _categoryService.GetAncestorsAsync(id);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting ancestors for category {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 获取分类的所有后代分类
        /// </summary>
        /// <param name="id">分类ID</param>
        /// <returns>后代分类列表</returns>
        [HttpGet("{id:long}/descendants")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<List<CategoryDto>>> GetDescendants(long id)
        {
            try
            {
                var result = await _categoryService.GetDescendantsAsync(id);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting descendants for category {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 批量更新排序权重
        /// </summary>
        /// <param name="sortData">排序数据</param>
        /// <returns>更新结果</returns>
        [HttpPost("batch-sort")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<bool>> BatchUpdateSort([FromBody] Dictionary<long, int> sortData)
        {
            try
            {
                var result = await _categoryService.BatchUpdateSortAsync(sortData);
                return Ok(new { success = result });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error batch updating sort weights");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 启用/禁用分类
        /// </summary>
        /// <param name="id">分类ID</param>
        /// <param name="request">启用/禁用请求</param>
        /// <returns>操作结果</returns>
        [HttpPost("{id:long}/toggle-enabled")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<bool>> SetEnabled(long id, [FromBody] SetEnabledRequest request)
        {
            try
            {
                var result = await _categoryService.SetEnabledAsync(id, request.Enabled);
                return Ok(new { success = result });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error setting enabled status for category {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 更新分类内容统计
        /// </summary>
        /// <param name="id">分类ID</param>
        /// <returns>更新结果</returns>
        [HttpPost("{id:long}/update-content-count")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<bool>> UpdateContentCount(long id)
        {
            try
            {
                var result = await _categoryService.UpdateContentCountAsync(id);
                return Ok(new { success = result });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error updating content count for category {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 检查分类名称是否存在
        /// </summary>
        /// <param name="name">分类名称</param>
        /// <param name="type">分类类型</param>
        /// <param name="parentId">父分类ID</param>
        /// <param name="excludeId">排除的分类ID</param>
        /// <returns>是否存在</returns>
        [HttpGet("exists")]
        [ProducesResponseType(200)]
        public async Task<ActionResult<bool>> Exists(
            [FromQuery] string name, 
            [FromQuery] string type, 
            [FromQuery] long? parentId = null, 
            [FromQuery] long? excludeId = null)
        {
            try
            {
                var result = await _categoryService.ExistsAsync(name, type, parentId, excludeId);
                return Ok(new { exists = result });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error checking if category exists");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 导出分类数据
        /// </summary>
        /// <param name="type">分类类型</param>
        /// <returns>导出文件</returns>
        [HttpGet("export")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult> Export([FromQuery] string? type = null)
        {
            try
            {
                var data = await _categoryService.ExportAsync(type);
                return File(data, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", 
                    $"categories-{type ?? "all"}-{DateTime.Now:yyyyMMddHHmmss}.xlsx");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error exporting categories");
                return BadRequest(new { message = ex.Message });
            }
        }

        /// <summary>
        /// 导入分类数据
        /// </summary>
        /// <param name="file">导入文件</param>
        /// <returns>导入结果</returns>
        [HttpPost("import")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<List<CategoryDto>>> Import(IFormFile file)
        {
            try
            {
                using var memoryStream = new MemoryStream();
                await file.CopyToAsync(memoryStream);
                var data = memoryStream.ToArray();
                
                var result = await _categoryService.ImportAsync(data);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error importing categories");
                return BadRequest(new { message = ex.Message });
            }
        }
    }

    /// <summary>
    /// 移动分类请求
    /// </summary>
    public class MoveCategoryRequest
    {
        /// <summary>
        /// 新父分类ID
        /// </summary>
        public long? NewParentId { get; set; }
    }

}
